using System;
using System.Reflection;
using UnityEditor;
using UnityEditor.ShortcutManagement;
using UnityEngine;

namespace DA.AnimGraph.Editor {
    public partial class AnimGraphEditorWindow {
        /// <summary>
        /// 菜单项打开
        /// </summary>
        [MenuItem("AnimGraph/Open Anim Graph Editor")]
        public static void OpenWindow() {
            // var window = EditorWindow.GetWindow<AnimGraphEditorWindow>("Anim Graph Editor");
            // 若已存在，则重新聚焦，否则打开新窗口，并尝试停靠
            AnimGraphEditorWindow window = FocusWindow(null);
            if (window == null) {
                window = NewWindow("Anim Graph Editor");
                Dock(window);
                window.InitWithPath(null);
                return;
            }
            window.Show(); // 出现过启动unity时窗口已实例化但没显示的问题
        }

        /// <summary>
        /// 重新打开窗口，在工具修改完之后往往需要全部刷新
        /// </summary>
        public void ReOpenWindow() {
            var path = this.path;
            Close();
            OpenWindow(path);
        }

        /// <summary>
        /// 双击文件 
        /// </summary>
        public static void OpenWindow(string path) {
            // 传统方式打开
            // var window = EditorWindow.GetWindow<AnimGraphEditorWindow>("Anim Graph Editor");
            // window.InitWithPath(path);

            // 若已存在，则重新聚焦，否则打开新窗口，并尝试停靠
            if (FocusWindow(path) == null) {
                var window = NewWindow("Anim Graph Editor");
                Dock(window);
                window.InitWithPath(path);
            }
        }

        static AnimGraphEditorWindow NewWindow(string title) {
            var window = ScriptableObject.CreateInstance(typeof(AnimGraphEditorWindow)) as AnimGraphEditorWindow;
            window.titleContent = new GUIContent(title);
            // instance.Show();
            return window;
        }

        internal static AnimGraphEditorWindow[] GetWindows() {
            AnimGraphEditorWindow[] windows = Resources.FindObjectsOfTypeAll<AnimGraphEditorWindow>();
            return windows;
        }

        /// <summary>
        /// 获取当前聚焦窗口
        /// </summary>
        static AnimGraphEditorWindow GetFocusedWindow() {
            AnimGraphEditorWindow[] windows = Resources.FindObjectsOfTypeAll<AnimGraphEditorWindow>();
            foreach (var window in windows) {
                if (window.hasFocus)
                    return window;
            }
            return null;
        }

        static AnimGraphEditorWindow FocusWindow(string path) {
            AnimGraphEditorWindow[] windows = Resources.FindObjectsOfTypeAll<AnimGraphEditorWindow>();
            foreach (var window in windows) {
                if (window.path == path) {
                    window.Focus();
                    return window;
                }
            }
            return null;
        }

        /// <summary>
        /// 将窗口停靠到其他同类窗口上，或者单独打开 
        /// </summary>
        static void Dock(AnimGraphEditorWindow newWindow) {
            var window = GetFocusedWindow();
            if (window == null) {
                newWindow.Show();
                return;
            }
            // 获取目标窗口的 Parent
            var parentField = typeof(EditorWindow).GetField("m_Parent", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            var targetParent = parentField.GetValue(window);
            // 将新窗口的 Parent 设置为目标窗口的 Parent
            var DockAreaType = typeof(EditorWindow).Assembly.GetType("UnityEditor.DockArea");
            Type[] parameterTypes = new[] { typeof(EditorWindow), typeof(bool) };
            var dockMethod = DockAreaType.GetMethod("AddTab", BindingFlags.Instance | BindingFlags.Public, null, parameterTypes, null);
            dockMethod.Invoke(targetParent, new object[] { newWindow, true });
        }


        /// <summary>
        /// 快捷键
        /// </summary>
        static class Shortcuts {
            [Shortcut("AnimGraphEditor/AnimGraphEditor: Save", typeof(AnimGraphEditorWindow), KeyCode.S, ShortcutModifiers.Action)]
            static void Save(ShortcutArguments args) {
                var window = GetFocusedWindow();
                if (window != null && window.isValid) {
                    window.ageEnv?.ageContext?.Save();
                }
            }

        }
    }
}
